#pragma once
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>

typedef struct
{
	uint8_t time_hour;	// UTC时间
	uint8_t time_minute;
	uint8_t time_second;
	uint16_t time_millisecond;
	uint8_t latitude_dd;	// 纬度
	uint8_t latitude_mm;
	uint32_t latitude_mmmmm;
	char latitude_direction;
	uint8_t longitude_ddd;	// 经度
	uint8_t	longitude_mm;
	uint32_t longitude_mmmmm;
	char longitude_direction;
	uint8_t status;		// GPS 定位模式/状态指示
	uint16_t satellites_number;	// 使用的卫星数
	float h_precision_factor;	// 水平精度因子
	float altitude;	// 平均海平面以上海拔
	char temp1;	// 
	float	geoidal_height;	// 大地水准面差距(WGS84 基准面与平均海平面之间的差值)
	char temp2;	// 
	uint8_t check_num;	// 校验和
}GNGGA;	 //全球定位系统定位数据

typedef struct
{
	uint8_t latitude_dd;	// 纬度
	uint8_t latitude_mm;
	uint32_t latitude_mmmmm;
	char latitude_direction;
	uint8_t longitude_ddd;	// 经度
	uint8_t	longitude_mm;
	uint32_t longitude_mmmmm;
	char longitude_direction;
	uint8_t time_hour;	// UTC时间
	uint8_t time_minute;
	uint8_t time_second;
	uint16_t time_millisecond;
	char pos_system_status;	// 定位系统状态
	char mode_indict;	// 模式指示
	uint8_t check_num;	// 校验和
}GNGLL;	// 地理位置—纬度和经度

typedef struct
{
	char mode;	// 模式
	uint8_t pos_mode;	// 定位模式
	uint8_t use_satellites_number[12];	// 使用卫星标识号
	float loc_precision_factor;	// 位置精度因子
	float h_precision_factor;	// 水平精度因子
	float v_precision_factor;	// 垂直精度因子
	uint8_t system_flag;	// GNSS系统标识符
	uint8_t check_num;	// 校验和
}GNGSA;	// GNSS 精度因子（DOP）与有效卫星

typedef struct {
	uint8_t sat_id;		// 卫星标识号
	uint8_t sat_elev;	// 仰角
	uint8_t sat_az;		// 真方位角
	uint8_t sat_cn0;	// 载躁比
}SAT_STATUS;

typedef struct
{
	uint8_t totalnumsen;	// 语句总数
	uint8_t sen_num;	// 语句号
	uint8_t total_num_sat;	// 可视的卫星总数
	SAT_STATUS sat_status[4];	// 
	uint8_t signal_id;	// 信号标识符
	uint8_t check_num;	// 校验和
}GPGSV;	// 可视的 GNSS 卫星   包含可视的卫星数、卫星标识号、仰角、方位角和信噪比

typedef struct
{
	uint8_t totalnumsen;	// 语句总数
	uint8_t sen_num;	// 语句号
	uint8_t total_num_sat;	// 可视的卫星总数
	SAT_STATUS sat_status[4];	// 
	uint8_t signal_id;	// 信号标识符
	uint8_t check_num;	// 校验和
}GLGSV;	// 可视的 GNSS 卫星   包含可视的卫星数、卫星标识号、仰角、方位角和信噪比

typedef struct
{
	uint8_t time_hour;	// UTC时间
	uint8_t time_minute;
	uint8_t time_second;
	uint16_t time_millisecond;
	char status;	// 定位系统状态
	uint8_t latitude_dd;	// 纬度
	uint8_t latitude_mm;
	uint32_t latitude_mmmmm;
	char latitude_direction;
	uint8_t longitude_ddd;	// 经度
	uint8_t	longitude_mm;
	uint32_t longitude_mmmmm;
	char longitude_direction;
	float sog;	// 对地速度
	float cog;	// 对地真航向
	uint8_t day;	// 日
	uint8_t month;	// 月
	uint8_t year;	// 年
	uint8_t	magvar;	// 磁偏角
	uint8_t magvar_dir;	// 磁偏角方向
	char model_ind;	// 模式指示
	char nav_status;	// 导航状态
	uint8_t check_num;	// 校验和
}GNRMC;	// 推荐的最少专用 GNSS 数据

typedef struct
{
	float cogt;	// 对地航向-真北
	char temp1;
	float cogm;	// 对地航向-磁北
	char temp2;
	float sogn;	// 对地速度-节
	char temp3;
	float sogk;	//对地速度-km/h
	char temp4;
	char mode; // 模式指示
	uint8_t check_num;	// 校验和
}GNVTG;		// 相对于地面的实际航向和速度

typedef struct
{
	uint8_t time_hour;	// UTC时间
	uint8_t time_minute;
	uint8_t time_second;
	uint16_t time_millisecond;
	uint8_t day;	// 日
	uint8_t month;	// 月
	uint16_t year;	// 年
	uint8_t temp1;
	uint8_t temp2;
	uint8_t check_num;	// 校验和
}GNZDA;	// 用于输出 UTC 时间，日、月、年及本地时区

typedef struct
{
	uint8_t total_num_sen;	// 语句总数
	uint8_t sen_num;	// 语句编号
	uint8_t text_id;	// 文本识别符
	char text_msg[20];	// 文本信息
	uint8_t check_num;	// 校验和
}GPTXT;	// 文本传送

typedef struct
{
	GNGGA gngga;
	GNGLL gngll;
	GNGSA gngsa[2];
	GPGSV gpgsv[4];
	GLGSV glgsv[4];
	GNRMC gnrmc;
	GNVTG gnvtg;
	GNZDA gnzda;
	GPTXT gptxt;
}NMEA;

const uint8_t gn_value[2] = { 0x47, 0x4E };
const uint8_t gl_value[2] = { 0x47, 0x4C };
const uint8_t gp_value[2] = { 0x47, 0x50 };
const uint8_t gga_value[3] = { 0x47, 0x47, 0x41 };
const uint8_t gll_value[3] = { 0x47, 0x4C, 0x4C };
const uint8_t gsa_value[3] = { 0x47, 0x53, 0x41 };
const uint8_t gsv_value[3] = { 0x47, 0x53, 0x56 };
const uint8_t rmc_value[3] = { 0x52, 0x4D, 0x43 };
const uint8_t vtg_value[3] = { 0x56, 0x54, 0x47 };
const uint8_t zda_value[3] = { 0x5A, 0x44, 0x41 };
const uint8_t txt_value[3] = { 0x54, 0x48, 0x54 };